#ifndef _TREE_H
#define _TREE_H
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef DATA_T data_t;

struct pretree;

typedef struct pretree tree;

struct pretree
{
    data_t data;
    tree* left;
    tree* right;
};

tree* tree_ctor();
int tree_dtor(tree* Tree);
int tree_ok(tree* Tree);
int tree_dump(tree* Tree, FILE* output);
int tree_filedump(tree* Tree, const char* FileName);
tree* new_node();
int add_node(tree* here, tree* this, char lor);
tree* MakeTree(const char* TextTree);
tree* MakeNode(FILE* source);


tree* tree_ctor(data_t data)
{
    tree* result = (tree*) calloc(1, sizeof(tree));
    result -> data = data;
    return result;
}

int tree_dtor(tree* Tree)
{
    if (!tree_ok(Tree)) return 0;
    if (Tree -> left)  tree_dtor(Tree -> left);
    if (Tree -> right) tree_dtor(Tree -> right);
    free(Tree);
    return 1;
}

int tree_ok(tree* Tree)
{
    if (!Tree) return 0;
    if (Tree -> right && Tree -> left) return tree_ok(Tree -> left)*tree_ok(Tree -> right);
    if (Tree -> right) return tree_ok(Tree -> right);
    if (Tree -> left) return tree_ok(Tree -> left);
    return 1;
}

int tree_dump(tree* Tree, FILE* output)
{
    if(!tree_ok(Tree)) return 0;

    fprintf(output, "(\"%s\"", Tree -> data);
    if (Tree -> left) tree_dump(Tree -> left, output);
    if (Tree -> right) tree_dump(Tree -> right, output);
    fprintf(output, "%c", ')');
    return 1;
}

int tree_filedump(tree* Tree, const char* FileName)
{
    if (!tree_ok(Tree)) return 0;
    FILE* dump = fopen(FileName, "w");
    if (!dump) return 0;
    int success = tree_dump(Tree, dump);
    fclose(dump);
    return success;
}

tree* new_node(data_t data)
{
    tree* result = (tree*) calloc(1, sizeof(tree));
    result -> data = data;
    return result;
}

int add_node(tree* here, tree* this, char lor)
{
    if(!tree_ok(here) || !tree_ok(this)) return 0;
    if (lor == 'l')
    {
        if (here -> left) return 0;
        here -> left  = this;
        return 1;
    }
    if (lor = 'r')
    {
        if (here -> right) return 0;
        here -> right = this;
        return 1;
    }
    return 0;
}

tree* MakeTree(const char* TextTree)
{
    FILE* source = fopen(TextTree, "r");
    if (!source) return NULL;
    fgetc(source);
    tree* Tree = MakeNode(source);
    fclose(source);
    return Tree;
}
tree* MakeNode(FILE* source)
{
    assert(source);
    char* str = (char*) calloc(100, sizeof(char));
    assert(str);

    fscanf(source, "\"%[^\"]\"", str);
    tree* Tree = new_node(str);
//printf("%p\n", Tree);
    assert(Tree);
    char c = fgetc(source);
//printf("%c\n", c);
    if (c == '(')
    {
        add_node(Tree, MakeNode(source), 'l');
        c = fgetc(source);
        if (c == '(') add_node(Tree, MakeNode(source), 'r');
        fgetc(source);
        return Tree;
    }
    //fgetc(source);
    return Tree;
}



#endif // _TREE_H
